//*****************************************************************************
//
//! \addtogroup Dots_c
//! @{
//
//*****************************************************************************

#include "dots.h"
#include "random.h"
#include "osram96x16x1.h"
#include "interrupt.h"
#include "hw_ints.h"


char misses=0;	///< counter of missed dots

extern unsigned char brdRow[2];
extern unsigned long secPlayed;

//*****************************************************************************
//
//! \internal
//! Initialize dots values.
//!
//! \param *dots is pointer to array of dots.
//!
//! Passes through all dots and declare them as free with empty mask.
//!
//! \return None.
//
//*****************************************************************************
static void init_dots(dot_t *dots)
{
	unsigned char i;
	for(i=0; i<MAX_DOTS; ++i) {
		dots[i].x = FREE;
		dots[i].mask[0] = 0x00;
		dots[i].mask[1] = 0x00;
	}
}

//*****************************************************************************
//
//! \internal
//! Move dots one pixel down.
//!
//! \param *dots is pointer to array of dots.
//!
//! Passes through all dots and
//! moves those of them which aren`t free one pixel down.
//! If dot is reached the bottom of display or it is caught
//! it is declared as free.
//! Draw non free dots on display.
//!
//! \return None.
//
//*****************************************************************************
static void move_dots(dot_t *dots)
{
		unsigned char nulls[2] = {0x00, 0x00};
		unsigned char i;
		for(i=0; i<MAX_DOTS; ++i) 
		{
			if(dots[i].x != FREE) 
			{
				dots[i].x--;
				// dot reach the bottom
				if(dots[i].x == 2)
				{
					if( ! ((brdRow[0] & dots[i].mask[0]) || (brdRow[1] & dots[i].mask[1]))) ++misses; // dot is caught
					else 
					{
						OSRAM96x16x1ImageDraw(nulls, dots[i].x+1, 0, 1, 2);
						dots[i].x = FREE;
					}
				}		
				// Draw dot on the display
				OSRAM96x16x1ImageDraw(dots[i].mask, dots[i].x,     0, 1, 2);
				OSRAM96x16x1ImageDraw(dots[i].mask, dots[i].x + 1, 0, 1, 2);
				OSRAM96x16x1ImageDraw(nulls,        dots[i].x + 2, 0, 1, 2);
				
			
			}
		}
}

//*****************************************************************************
//
//! \internal
//! Add dot to display.
//!
//! \param *dots is pointer to array of dots.
//!
//! Searches for free dot in dots array and gives it starting position and mask.
//!
//! \return 1 on succsses (free dot was found), otherwise 0.
//
//*****************************************************************************
static int add_dot(dot_t *dots)
{
	unsigned char i;
	unsigned short hlp, stPos = 0x03;
	unsigned long pos;

	//search for free dot
	for(i=0; i<MAX_DOTS; ++i) 
	{
		if(dots[i].x == FREE) 
		{ //free dot found
			dots[i].x = 96;

			pos = RandomNumber() % 15;

			stPos <<= pos;
			dots[i].mask[0] = (unsigned char) stPos;
			hlp = stPos >> 8;
			dots[i].mask[1] = (unsigned char) hlp;
						 	  
			return 1;
		}
	}
	return 0; //free dot not found check again later
}

//*****************************************************************************
//
//! Main loop of the game.
//!
//! Calculates when to add dots and
//! breaks when player makes 100 misses.
//! On each 20 seconds increase the game speed.
//!
//! \return None.
//
//*****************************************************************************
void playGame(void)
{
	unsigned long when;
	unsigned long dlay = 200000;
	unsigned long i;
	dot_t dots[MAX_DOTS];
	
	// Disabling interupts from user button preventing it from slowing down program execution
	IntDisable(INT_GPIOC);

	when = RandomNumber() % ROWS + 2;
	init_dots(dots);
	add_dot(dots);

	while(1)
	{
		//add dot
		if(when == 0) 
		{
			if(!add_dot(dots)) ++when; //there is no free dots check next time
			else when = RandomNumber() % ROWS + 2; // calculate next time for new dot
		}

		move_dots(dots);

		// Draw doard
		DrawBoard();

		// Check for game over :)
		if(misses == 100) {
		//stops the game
			break;
		}

		// Delay
		for(i=dlay; i; --i);

		// Lower delay time for adding dot thus increasing game speed
		if (secPlayed % 31 == 30 && dlay>10000)
			{
			OSRAM96x16x1Clear();
			OSRAM96x16x1StringDraw("Changing speed!", 0 ,0);
			for(i=0; i < 2000000; ++i);
			OSRAM96x16x1Clear();
			dlay -= 50000;
			}
		 
		--when;
	}
	// Zeroing the counter for missed points for further play
	misses = 0;

	// Enabling button interrupts so that another game could be played
	IntEnable(INT_GPIOC);	
}


//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
